package com.hbu.product.hbumallproduct.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hbu.common.utils.Constant;
import com.hbu.common.utils.PageUtils;
import com.hbu.common.utils.Query;
import com.hbu.product.hbumallproduct.dao.BrandDao;
import com.hbu.product.hbumallproduct.entity.BrandEntity;
import com.hbu.product.hbumallproduct.event.BrandDataSynchronizer;
import com.hbu.product.hbumallproduct.event.BrandEvent;
import com.hbu.product.hbumallproduct.service.BrandService;
import com.hbu.product.hbumallproduct.utils.ConnPool;
import com.hbu.product.hbumallproduct.utils.ConnectionContext;
import com.hbu.product.hbumallproduct.utils.SqlUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Map;
import java.util.concurrent.CountDownLatch;


/**
 * @author 90458
 */
@Service("brandService")
@AllArgsConstructor
public class BrandServiceImpl extends ServiceImpl<BrandDao, BrandEntity> implements BrandService {

    private ApplicationEventPublisher applicationEventPublisher;

    private ConnPool connPool;

    private ApplicationContext applicationContext;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String key = (String) params.get(Constant.KEY);
        QueryWrapper<BrandEntity> wrapper = new QueryWrapper<>();
        if (StringUtils.hasText(key)) {
            wrapper.eq("brand_id", key).or().like("name", key);
        }
        IPage<BrandEntity> page = this.page(
                new Query<BrandEntity>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

    @Override
    @SneakyThrows
    public void updateDetail(BrandEntity brand) {
        Connection connection = connPool.getConnection();
        connection.setAutoCommit(false);
        SQL brandUpdateSql = new SQL().UPDATE("pms_brand");
        SqlUtil.updateUtil(brand, brandUpdateSql);
        brandUpdateSql.WHERE("brand_id = " + brand.getBrandId());
        log.debug("执行的sql语句为 : " + brandUpdateSql);
        PreparedStatement preparedStatement = connection.prepareStatement(brandUpdateSql.toString());
        preparedStatement.executeUpdate();
        preparedStatement.close();
        // 如果此次更新中有对brand_name的内容进行更新的操作，就需要将关联表中的冗余字段也作更新，考虑到内容耦合，改为观察者模式
        if (StringUtils.hasText(brand.getName())) {
            ConnectionContext.setConnection(connection);
            int synchronizerNum = applicationContext.getBeanNamesForType(BrandDataSynchronizer.class).length;
            CountDownLatch countDownLatch = new CountDownLatch(synchronizerNum);
            applicationEventPublisher.publishEvent(new BrandEvent(this, brand, countDownLatch));
            countDownLatch.await();
            ConnectionContext.clear();
        }
        connection.commit();
        connPool.free(connection);
    }

}